package org.tim.es.message;

import lombok.var;
import org.apache.logging.log4j.util.Strings;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.tim.es.ElasticsearchConstants;

import java.time.LocalDateTime;
import java.util.concurrent.Executors;

public interface UserPrivateMessageResource extends ElasticsearchRepository<UserPrivateMessage, String> {
    default Page<UserPrivateMessage> findAllBySessionId(String sessionId, Integer page, Integer pageSize) {
        BoolQueryBuilder bQuery = new BoolQueryBuilder();
        if (Strings.isNotEmpty(sessionId)) {
            bQuery.must(new TermQueryBuilder("sessionId", sessionId));
        }

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder().withQuery(bQuery);

        /* 根据最后的会话时间排序 */
        FieldSortBuilder startAtOrder_asc = SortBuilders.fieldSort("sendAt");
        startAtOrder_asc.order(SortOrder.DESC);
        queryBuilder.withSort(startAtOrder_asc);

        NativeSearchQuery searchQuery = queryBuilder.withPageable(PageRequest.of(page, pageSize)).build();

        return this.search(searchQuery);
    }

    void deleteAllBySessionId(String sessionId);

    default void updateAllUnRead(String sessionId, LocalDateTime deadline) {
        BoolQueryBuilder bQuery = new BoolQueryBuilder();
        if (Strings.isNotEmpty(sessionId)) {
            bQuery.must(new TermQueryBuilder("sessionId", sessionId));
        }
        bQuery.must(new TermQueryBuilder("read", false));

        var startAt = ElasticsearchConstants.DATE_HOUR_MINUTE_SECOND.format(deadline);
        bQuery.must().add(new RangeQueryBuilder("sendAt").lte(startAt));

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder().withQuery(bQuery);

        NativeSearchQuery searchQuery = queryBuilder.withPageable(PageRequest.of(0, 5000)).build();

        final Page<UserPrivateMessage> messages = this.search(searchQuery);
        Executors.newFixedThreadPool(2).submit(new Runnable() {
            @Override
            public void run() {
                for (UserPrivateMessage message : messages) {
                    message.setRead(Boolean.TRUE);
                    save(message);
                }
            }
        });
    }
}
